home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 1999 August / Macworld (1999-08).dmg / Shareware World / Info / For Developers / MADE 1.4.0 / Essentials / Essential Events.c < prev    next >
Text File  |  1999-05-26  |  11KB  |  437 lines

  1. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  2. /*                                                                   */
  3. /*        MADE - Macintosh Application Development Essentials        */
  4. /*        ---------------------------------------------------        */
  5. /*           (c) Sig Software, http://www.sigsoftware.com/           */
  6. /*                                                                   */
  7. /* These files can only be used for experimental purposes. To obtain */
  8. /* fully commented code, source code for the functions in Essential  */
  9. /*   Extras.h and permission for usage in final projects, you must   */
  10. /*    purchase a license. See documentation for more information.    */
  11. /*                                                                   */
  12. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  13. /*                                                                   */
  14. /*  Essential Events.c                                               */
  15. /*  ------------------                                               */
  16. /*                                                                   */
  17. /*  Event and AppleEvent handling.                                   */
  18. /*                                                                   */
  19. /*  Version 1.0.0 - 10th November 1996                               */
  20. /*  Version 1.1.0 - 29th January 1998 - Modeless dialog support      */
  21. /*  Version 1.2.0 - 20th November 1998 - Avoids C/C++ warnings       */
  22. /*                                       Open App event support      */
  23. /*                                       Suspend/resume events       */
  24. /*  Version 1.4.0 - 26th May 1999 - Rearranged, threads, appInFront  */
  25. /*                                                                   */
  26. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  27.  
  28. #include "Essential Headers.h"
  29. #include "Essential Prototypes.h"
  30. #include "Essential Extras.h"
  31.  
  32. WindowPtr    frontWindow=0;
  33. Boolean        appInFront=true;
  34.  
  35. #if Use_AppleEvents
  36.  
  37. #include <AppleEvents.h>
  38.  
  39. #if Handle_Open_Application_Event
  40. pascal OSErr        EventOpenAppHandler(AppleEvent*, AppleEvent*, long);
  41. AEEventHandlerUPP    EventOpenAppUPP;
  42. #endif
  43.  
  44. #if Handle_Open_Documents_Event
  45. pascal OSErr        EventOpenDocHandler(AppleEvent*, AppleEvent*, long);
  46. AEEventHandlerUPP    EventOpenDocUPP;
  47. #endif
  48.  
  49. #if Handle_Print_Documents_Event
  50. pascal OSErr        EventPrintDocHandler(AppleEvent*, AppleEvent*, long);
  51. AEEventHandlerUPP    EventPrintDocUPP;
  52. #endif
  53.  
  54. #if Handle_Quit_Application_Event
  55. pascal OSErr        EventQuitAppHandler(AppleEvent*, AppleEvent*, long);
  56. AEEventHandlerUPP    EventQuitAppUPP;
  57. #endif
  58.  
  59. #endif
  60.  
  61. void MainEventLoop()
  62. {
  63.     EventRecord    theEvent;
  64.     Point        localPoint;
  65.     
  66. #if Add_Threads_Support
  67.     WaitNextEvent(everyEvent, &theEvent,
  68.         ThreadsBusy() ? Event_Sleep_Time_If_Threads_Busy : Event_Sleep_Time, 0);
  69. #else
  70.     WaitNextEvent(everyEvent, &theEvent, Event_Sleep_Time, 0);
  71. #endif
  72.     
  73.     if (frontWindow) {
  74.         localPoint=theEvent.where;
  75.         GlobalToLocal(&localPoint);
  76.         MySetTheCursor(localPoint);
  77.     } else
  78.         SetCursor(&qd.arrow);
  79.  
  80.     ProcessEvent(&theEvent);
  81. }
  82.  
  83. void ProcessEvent(EventRecord* theEvent)
  84. {
  85.     char        keyCharacter;
  86.     short        mousePart;
  87.     WindowPtr    mouseWindow, oldPort;
  88.     DialogPtr    theDialog;
  89.     Rect        growLimits;
  90.     long        growResult;
  91.     Point        localPoint;
  92.     Error        error=0;
  93.     
  94.     mousePart=FindWindow(theEvent->where, &mouseWindow);
  95.     
  96.     if (mousePart==inContent) {
  97.         localPoint=theEvent->where;
  98.         
  99.         GetPort(&oldPort);
  100.         SetPort(mouseWindow);
  101.         GlobalToLocal(&localPoint);
  102.         SetPort(oldPort);
  103.     }
  104.     
  105. #if Support_Modeless_Dialogs
  106.  
  107.     if (IsDialogEvent(theEvent)) {
  108.         switch (theEvent->what) {
  109.             case mouseDown:
  110.                 theDialog=mouseWindow;
  111.                 break;
  112.             
  113.             case activateEvt:
  114.                 if (theEvent->modifiers&activeFlag) {
  115.                     frontWindow=(WindowPtr)theEvent->message;
  116.                     SetPort(frontWindow);
  117.                 } else
  118.                     frontWindow=0;
  119.             case updateEvt: 
  120.                 theDialog=(WindowPtr)theEvent->message;
  121.                 break;
  122.             
  123.             case nullEvent:
  124.                 MyPerformIdleTasks();
  125.                 return;
  126.             
  127.             default:
  128.                 theDialog=FrontWindow();
  129.                 break;
  130.         }
  131.         
  132.         if (MyDialogFilter(theDialog, theEvent, &mousePart) ||
  133.                 DialogSelect(theEvent, &theDialog, &mousePart))
  134.             MyHandleDialogEvent(theEvent, theDialog, mousePart);
  135.             
  136.         return;
  137.     }
  138.  
  139. #endif
  140.  
  141.     switch (theEvent->what) {
  142.  
  143.         case nullEvent:
  144.             MyPerformIdleTasks();
  145.             break;
  146.             
  147.         case keyDown: case autoKey: // keyDown and autoKey not distinguished between
  148.             keyCharacter=(char)(theEvent->message&charCodeMask);
  149.             if (theEvent->modifiers&cmdKey) {
  150.                 MyEnableMenus();
  151.                 SelectMenuItem(MenuKey(keyCharacter));
  152.             } else
  153.                 MyHandleKeyDown(keyCharacter, theEvent);
  154.             break;
  155.             
  156.         case mouseDown:
  157.             switch (mousePart) {
  158.                 case inMenuBar:
  159.                     MyEnableMenus();
  160.                     SelectMenuItem(MenuSelect(theEvent->where));
  161.                     break;
  162.                     
  163.                 case inSysWindow:
  164.                     SystemClick(theEvent, mouseWindow);
  165.                     break;
  166.                     
  167.                 case inContent:
  168.                     if (mouseWindow==frontWindow)
  169.                         MyHandleMouseDown(localPoint, theEvent);
  170.                     else
  171.                         SelectWindow(mouseWindow);
  172.                     break;
  173.                     
  174.                 case inDrag:
  175.                     DragWindow(mouseWindow, theEvent->where, &qd.screenBits.bounds);
  176.                     break;
  177.                     
  178.                 case inGrow:
  179.                     if (mouseWindow==frontWindow) {
  180.                         MyResizeBounds(&growLimits);
  181.                         growResult=GrowWindow(frontWindow, theEvent->where, &growLimits);
  182.  
  183.                         if (growResult) {
  184.                             SizeWindow(frontWindow, LoWord(growResult), HiWord(growResult), true);
  185.                                 // last parameter specifies that new bit should be updated
  186.                             MySizedWindow();
  187.                         }
  188.                     } else
  189.                         SelectWindow(mouseWindow);
  190.                     break;
  191.                     
  192.                 case inGoAway:
  193.                     if (mouseWindow==frontWindow) {
  194.                         if (TrackGoAway(frontWindow, theEvent->where)) {
  195.                             MyCloseWindow();
  196.                             frontWindow=0;
  197.                         }
  198.  
  199.                     } else
  200.                         SelectWindow(mouseWindow);
  201.                     break;
  202.                     
  203.                 case inZoomIn: case inZoomOut:
  204.                     if (mouseWindow==frontWindow) {
  205.                         if (TrackBox(frontWindow, theEvent->where, mousePart)) {
  206.                             ZoomWindow(frontWindow, mousePart, false);
  207.                                 // All sorts of things could be done here but this is default behaviour
  208.                             MySizedWindow();
  209.                         }
  210.  
  211.                     } else
  212.                         SelectWindow(mouseWindow);
  213.                     break;
  214.             }
  215.             break;
  216.             
  217.         case updateEvt:
  218.             BeginUpdate((WindowPtr)theEvent->message);
  219.             GetPort(&oldPort);
  220.             SetPort((WindowPtr)theEvent->message);
  221.             MyDrawWindow((WindowPtr)theEvent->message);
  222.             SetPort(oldPort);
  223.             EndUpdate((WindowPtr)theEvent->message);
  224.             break;
  225.             
  226.         case activateEvt:
  227.             if (theEvent->modifiers&activeFlag) {
  228.                 frontWindow=(WindowPtr)theEvent->message;
  229.                 SetPort(frontWindow);
  230.                     // This is essential - all window-based actions depend on this call
  231.                 MyActivateWindow();
  232.  
  233.             } else {
  234.                 MyDeactivateWindow();
  235.                 frontWindow=0;
  236.             }
  237.             break;
  238.             
  239.         case osEvt:
  240.             if ((theEvent->message&osEvtMessageMask)>>24==suspendResumeMessage) {
  241.                 if (theEvent->message&1) {
  242.                     appInFront=true;
  243.                     MyResumeApplication();
  244.  
  245.                 } else {
  246.                     appInFront=false;
  247.                     MySuspendApplication();
  248.                 }
  249.             }
  250.             break;
  251.             
  252. #if Use_AppleEvents
  253.         case kHighLevelEvent:
  254.             error=AEProcessAppleEvent(theEvent);
  255.             if (error!=errAEEventNotHandled)
  256.                 TestError(error);
  257.             break;
  258. #endif
  259.  
  260.     }
  261. }    
  262.  
  263. #if Use_AppleEvents
  264.  
  265. Error CheckRequiredParams(AppleEvent *appleEvent)
  266. {
  267.     Error        error=0;
  268.     DescType    returnType;
  269.     Size        actualSize;
  270.  
  271.     error=AEGetAttributePtr(appleEvent, keyMissedKeywordAttr,
  272.         typeWildCard, &returnType, 0, 0, &actualSize);
  273.  
  274.     if (error==errAEDescNotFound)
  275.         error=0;
  276.     else if (error==0)
  277.         error=errAEEventNotHandled;
  278.  
  279.     return error;
  280. }
  281.  
  282. Error InitAppleEvents()
  283. {
  284.     Error    error=0;
  285.     
  286.     // NOTE: the refCon parameter in the AEInstallEventHandler call need not be zero; you can
  287.     // pass a long word in that will get given to your handlers when they are called
  288.  
  289. #if Handle_Open_Application_Event
  290.  
  291.     EventOpenAppUPP=NewAEEventHandlerProc(EventOpenAppHandler);
  292.     error=AEInstallEventHandler(
  293.         kCoreEventClass, kAEOpenApplication, EventOpenAppUPP, 0, false);
  294.     TestError(error);
  295.         _i(error)
  296.  
  297. #endif    
  298.  
  299. #if Handle_Open_Documents_Event
  300.  
  301.     EventOpenDocUPP=NewAEEventHandlerProc(EventOpenDocHandler);
  302.     error=AEInstallEventHandler(
  303.         kCoreEventClass, kAEOpenDocuments, EventOpenDocUPP, 0, false);
  304.     TestError(error);
  305.         _i(error)
  306.  
  307. #endif
  308.  
  309. #if Handle_Print_Documents_Event
  310.  
  311.     EventPrintDocUPP=NewAEEventHandlerProc(EventPrintDocHandler);
  312.     error=AEInstallEventHandler(
  313.         kCoreEventClass, kAEPrintDocuments, EventPrintDocUPP, 0, false);
  314.     TestError(error);
  315.         _i(error)
  316.  
  317. #endif
  318.  
  319. #if Handle_Quit_Application_Event
  320.  
  321.     EventQuitAppUPP=NewAEEventHandlerProc(EventQuitAppHandler);
  322.     error=AEInstallEventHandler(
  323.         kCoreEventClass, kAEQuitApplication, EventQuitAppUPP, 0, false);
  324.     TestError(error);
  325.     
  326. #endif
  327.  
  328.     _e
  329.     return error;
  330. }
  331.  
  332. #if    Handle_Open_Application_Event
  333.     
  334. pascal OSErr EventOpenAppHandler(AppleEvent* eventIn, AppleEvent* eventOut, long refCon)
  335. {
  336.     Error    error;
  337.     
  338.     error=CheckRequiredParams(eventIn);
  339.         _i(error)
  340.     
  341.     MyOpenApplication();
  342.  
  343.     _e
  344.     return error;
  345. }
  346.     
  347. #endif
  348.  
  349. #if Handle_Open_Documents_Event
  350.  
  351. pascal OSErr EventOpenDocHandler(AppleEvent* eventIn, AppleEvent* eventOut, long refCon)
  352. {
  353.     AEDescList    docList;
  354.     DescType    returnType;
  355.     Size        actualSize;
  356.     long        docNum, numDocs;
  357.     FSSpec        fileSpec;
  358.     AEKeyword    keyword;
  359.     Error        error=0;
  360.     
  361.     error=AEGetParamDesc(eventIn, keyDirectObject, typeAEList, &docList);
  362.         _i(error)
  363.     error=CheckRequiredParams(eventIn);
  364.         _i(error)
  365.     error=AECountItems(&docList, &numDocs);
  366.         _i(error)
  367.     
  368.     for (docNum=1; docNum<=numDocs; docNum++) {
  369.         error=AEGetNthPtr(&docList, docNum, typeFSS, &keyword,
  370.             &returnType, &fileSpec, sizeof(fileSpec), &actualSize);
  371.             _i(error)
  372.         
  373.         MyOpenDocument(&fileSpec);
  374.     }
  375.     
  376.     error=AEDisposeDesc(&docList);
  377.  
  378.     _e
  379.     return error;
  380. }
  381.     
  382. #endif
  383.  
  384. #if Handle_Print_Documents_Event
  385.  
  386. pascal OSErr EventPrintDocHandler(AppleEvent* eventIn, AppleEvent* eventOut, long refCon)
  387. {
  388.     AEDescList    docList;
  389.     DescType    returnType;
  390.     Size        actualSize;
  391.     long        docNum, numDocs;
  392.     FSSpec        fileSpec;
  393.     AEKeyword    keyword;
  394.     Error        error=0;
  395.     
  396.     error=AEGetParamDesc(eventIn, keyDirectObject, typeAEList, &docList);
  397.         _i(error)
  398.     error=CheckRequiredParams(eventIn);
  399.         _i(error)
  400.     error=AECountItems(&docList, &numDocs);
  401.         _i(error)
  402.     
  403.     for (docNum=1; docNum<=numDocs; docNum++) {
  404.         error=AEGetNthPtr(&docList, docNum, typeFSS, &keyword,
  405.             &returnType, &fileSpec, sizeof(fileSpec), &actualSize);
  406.             _i(error)
  407.         
  408.         MyPrintDocument(&fileSpec);
  409.     }
  410.     
  411.     error=AEDisposeDesc(&docList);
  412.  
  413.     _e
  414.     return error;
  415. }
  416.     
  417. #endif
  418.  
  419. #if Handle_Quit_Application_Event
  420.  
  421. pascal OSErr EventQuitAppHandler(AppleEvent* event, AppleEvent*, long)
  422. {
  423.     Error    error=0;
  424.     
  425.     error=CheckRequiredParams(event);
  426.         _i(error);
  427.     
  428.     applicationHasQuit=true;
  429.  
  430.     _e
  431.     return error;
  432. }
  433.     
  434. #endif
  435.  
  436. #endif
  437.